unit categorie_frm;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, db, FileUtil, LResources, Forms, Controls, Graphics,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls, DBGrids,  ZDataset,datamodule_frm;

type

  { TCategorie }

  TCategorie = class(TForm)
    btelimina: TButton;
    bteliminaext: TButton;
    btnuovo: TButton;
    btnuovoext: TButton;
    btsalva: TButton;
    btimage: TButton;
    btsalvaext: TButton;
    bttemplate: TButton;
    cbCategorie: TComboBox;
    cbCategoriaParent: TComboBox;
    cbtemplate: TComboBox;
    ckgerarchica: TCheckBox;
    Datasource1: TDatasource;
    edcampo: TLabeledEdit;
    edDescrizione: TMemo;
    edgruppo: TLabeledEdit;
    edimage: TEdit;
    edvalore: TLabeledEdit;
    grigliacampi: TDBGrid;
    Image1: TImage;
    Label1: TLabel;
    edNome: TLabeledEdit;
    Label2: TLabel;
    Label3: TLabel;
    lblCategoriaMadre: TLabel;
    lblDescrizione: TLabel;
    lblNote: TLabel;
    OpenDialog1: TOpenDialog;
    Panel2: TPanel;
    Panel3: TPanel;
    zq_categorie: TZQuery;
    zq_ext: TZQuery;
    procedure bteliminaClick(Sender: TObject);
    procedure bteliminaextClick(Sender: TObject);
    procedure btnuovoClick(Sender: TObject);
    procedure btsalvaClick(Sender: TObject);
    procedure btimageClick(Sender: TObject);
    procedure btnuovoextClick(Sender: TObject);
    procedure btsalvaextClick(Sender: TObject);
    procedure bttemplateClick(Sender: TObject);
    procedure cbCategorieChange(Sender: TObject);
    procedure cbCategorieExit(Sender: TObject);
    procedure cbCategorieKeyPress(Sender: TObject; var Key: char);
    procedure ckgerarchicaChange(Sender: TObject);
    procedure edNomeChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure grigliacampiCellClick(Column: TColumn);
    procedure grigliacampiDblClick(Sender: TObject);
    procedure LoadComboCategorie();
        procedure LoadComboTemplate();
    procedure getcategorychild(categoryparent,level:integer);
    procedure LoadComboCategorieparent();
    procedure getcategorychildparent(categoryparent,level:integer);
    procedure ClearCampi();
  private
    { private declarations }
  public
    { public declarations }
    idcategoria_sel:integer;
  end; 

var
  Categorie: TCategorie;


implementation

{ TCategorie }


procedure Tcategorie.LoadComboTemplate();
begin
     cbTemplate.Clear;
     with zq_categorie do
        begin
             Close;
             sql.Clear;
             sql.Add('SELECT IDTEMPLATE, IDDITTA, NOME_TEMPLATE FROM CATEGORIE_TEMPL');
             sql.add('WHERE IDDITTA=:IDDITTA');
             ParamByName('IDdITTA').AsInteger:=DataModule1.idditta;
             ExecSQL;
             Open;
             while not EOF do
             begin
                  //carico il campo NOME di ogni singolo record nella combo di visualizzazione
                  cbTemplate.Items.AddObject(FieldByName('NOME_TEMPLATE').AsString,TObject(FieldByName('IDTEMPLATE').AsInteger));
                  Next;
             end;
        end
end;

procedure TCategorie.FormShow(Sender: TObject);
begin
    LoadComboCategorie();
  LoadComboCategorieparent();
  if idcategoria_sel<>0 then
     begin
          cbCategorie.ItemIndex:=cbCategorie.Items.IndexOfObject(TObject(idcategoria_sel));
          cbCategorieChange(self);
     end;
  LoadComboTemplate();
end;

procedure TCategorie.grigliacampiCellClick(Column: TColumn);
begin
   grigliacampiDblClick(self);
end;

procedure TCategorie.grigliacampiDblClick(Sender: TObject);
begin
    //carico i dati nella form di modifica
 edcampo.Text:=zq_ext.FieldByName('Nome_campo').AsString;
 edvalore.Text:=zq_ext.FieldByName('valore').AsString;
 edgruppo.Text:=zq_ext.FieldByName('Gruppo').AsString;
  //se viene selezionata una cella cambio la caption del pulsante per il salvataggio
  btsalvaext.Caption:='Salva';
  bteliminaext.Enabled:=true;
end;

procedure TCategorie.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  CloseAction:=caFree;
end;

procedure TCategorie.FormCreate(Sender: TObject);
begin
//inizializzo le variabili
  idcategoria_sel:=0;
end;


procedure Tcategorie.btnuovoextClick(Sender: TObject);
begin
// deseleziono i record delle estensioni
  //cambio la caption del pulsante per salvare
  //refresho la griglia e pulisco i campi
  if zq_ext.Active then
    zq_ext.Refresh;
  edcampo.Clear;
  edvalore.Clear;
  edgruppo.Clear;
  btsalvaext.Caption:='Aggiungi';
  bteliminaext.Enabled:=false;
end;

procedure TCategorie.btnuovoClick(Sender: TObject);
begin
  //pulisce tutti i campi per consentire un nuovo inserimento
  ClearCampi();
  edNome.SetFocus;
end;

procedure TCategorie.btsalvaClick(Sender: TObject);
var
   id_categoria_inserita : Integer;
   stream:TMemoryStream;
begin
  //CONTROLLI
  stream:=TMemoryStream.create;
  if cbCategoriaParent.Text='' then
  begin
     ShowMessage('Devi selezionare una categoria madre.');
     cbCategoriaParent.SetFocus;
     Exit();
  end;
  //categoria non può essere madre di se stessa
  if cbCategorie.Text=cbCategoriaParent.Text then
  begin
     ShowMessage('La categoria non può essere figlia di se stessa.');
     cbCategoriaParent.SetFocus;
     Exit();
  end;
  if ednome.Text='' then
  begin
     ShowMessage('Devi indicare almeno il nome della categoria.');
     edNome.SetFocus;
     Exit();
  end;

  if cbCategorie.Text<>'' then
  begin
     ////////////////////////////////////////////////////////////////////
     ///              Modifica Categoria
     ////////////////////////////////////////////////////////////////////
     with zq_categorie do
          begin
               Close;
               sql.Clear;
               sql.Add('UPDATE CATEGORIE SET '+
                       'NOME=:NOME,'+
                       'DESCRIZIONE=:DESCRIZIONE, '+
                       'GERARCHICA=:GERARCHICA, '+
                       'immagine=:IMMAGINE '+
                       'WHERE IDCATEGORIA=:ID');
               ParamByName('NOME').AsString:=edNome.Text;
               ParamByName('DESCRIZIONE').AsString:=edDescrizione.Text;
               ParamByName('ID').AsInteger:=integer(cbCategorie.Items.Objects[cbCategorie.ItemIndex]);
               if ckgerarchica.Checked then
                  ParamByName('GERARCHICA').AsInteger:=1
               else
                  ParamByName('GERARCHICA').AsInteger:=0;

               if not Image1.Picture.Jpeg.Empty then
                  begin
                       Image1.Picture.SaveToStreamWithFileExt(stream,'jpg');
                       ParamByName('immagine').LoadFromStream(stream,ftblob);
                  end
               else
                   ParamByName('immagine').IsNull;
               ExecSQL;

               sql.Clear;
               sql.Add('UPDATE CATEGORIE_REL SET '+
                     'ID_CATEGORIA_PARENT=:PARENT '+
                     'WHERE ID_CATEGORIA_CHILD=:CHILD');
               ParamByName('PARENT').AsInteger:=integer(cbCategoriaParent.Items.Objects[cbCategoriaParent.ItemIndex]);
               ParamByName('CHILD').AsInteger:=integer(cbCategorie.Items.Objects[cbCategorie.ItemIndex]);
               ExecSQL;

               LoadComboCategorie();
               LoadComboCategorieparent();
               //comunica l'esito positivo della modifica
               ShowMessage(ednome.Text+ ' è stata modificata correttamente.');

          end;
  end
  else
  begin
     ////////////////////////////////////////////////////////////////////
     ///              INSERIMENTO CATEGORIA
     ////////////////////////////////////////////////////////////////////
     with zq_categorie do
     begin
          Close;
          sql.Clear;
          sql.Add('INSERT INTO CATEGORIE ('+
                     'NOME,'+
                     'DESCRIZIONE,'+
                     'GERARCHICA,' +
                     'IDDITTA,' +
                     'IMMAGINE' +
                     ') VALUES (:NOME,:DESCRIZIONE, :GERARCHICA,:IDDITTA, :IMMAGINE)');
          ParamByName('NOME').AsString:=edNome.Text;
          ParamByName('DESCRIZIONE').AsString:=edDescrizione.Text;
          if ckgerarchica.Checked then
             ParamByName('GERARCHICA').AsInteger:=1
          else
              ParamByName('GERARCHICA').AsInteger:=0;
          ParamByName('IDDITTA').AsInteger:=DataModule1.idditta;
          if not Image1.Picture.Jpeg.Empty then
             begin
                  Image1.Picture.SaveToStreamWithFileExt(stream,'jpg');
                  ParamByName('immagine').LoadFromStream(stream,ftblob);
             end
          else
             ParamByName('immagine').IsNull;

          ExecSQL;

          sql.Clear;
          sql.Add('SELECT MAX(IDCATEGORIA) AS IDCATCORRENTE FROM CATEGORIE');
          sql.Add('WHERE IDDITTA=:IDDITTA');
          ParamByName('IDDITTA').AsInteger:=DataModule1.idditta;
          ExecSQL;
          Open;
          id_categoria_inserita := zq_categorie.FieldByName('IDCATCORRENTE').AsInteger;

          sql.Clear;
          sql.Add('INSERT INTO CATEGORIE_REL ('+
                     'ID_CATEGORIA_PARENT,'+
                     'ID_CATEGORIA_CHILD'+
                     ') VALUES (:PARENT,:CHILD)');
          ParamByName('PARENT').AsInteger:=integer(cbCategoriaParent.Items.Objects[cbCategoriaParent.ItemIndex]);
          ParamByName('CHILD').AsInteger:=id_categoria_inserita;
          ExecSQL;

          //riaggiorna la lista delle ditte
          LoadComboCategorie();
          LoadComboCategorieparent();
          //comunica l'esito positivo dell'inserimento
          ShowMessage(edNome.Text+' è stato creato.');
     end
   end;
   btnuovoextClick(self);
   btnuovoClick(self);
   stream.destroy;
end;

procedure TCategorie.bteliminaClick(Sender: TObject);
var
  buttonSelected : Integer;
begin
   //CONTROLLI
   //controllo che sia stata selezionato un utente sennò avverto
   //che è necessario selezionarne uno
   if cbCategorie.ItemIndex=-1 then
   begin
        ShowMessage('Per eliminare una categoria è necessario prima selezionarne una dalla lista.');
        exit();
   end;

    //se la categoria ha figli non eliminare e comunica di eliminare prima i figli
    with zq_categorie do
    begin
         Close;
         sql.Clear;
         sql.Add('SELECT * FROM CATEGORIE_REL WHERE ID_CATEGORIA_PARENT = :ID');
         ParamByName('ID').AsInteger:=integer(cbCategorie.Items.Objects[cbCategorie.ItemIndex]);
         ExecSQL;
         Open;
         if RecordCount>0 then
         begin
            ShowMessage(cbCategorie.Text+ ' ha categorie figlie. Eliminare prima le sue categorie figlie.');
            exit();
         end
    end;
    buttonSelected := MessageDlg('Si sta per eliminare la categoria '+cbCategorie.Text+'. Continuare?',mtInformation, mbOKCancel, 0);
    if buttonSelected = mrOK     then
    begin
         with zq_categorie do
         begin
              Close;
              sql.Clear;
              sql.Add('DELETE FROM CATEGORIE_REL WHERE ID_CATEGORIA_CHILD=:ID');
              ParamByName('ID').AsInteger:=integer(cbCategorie.Items.Objects[cbCategorie.ItemIndex]);
              ExecSQL;

              Close;
              sql.Clear;
              sql.Add('DELETE FROM CATEGORIE WHERE IDCATEGORIA=:ID');
              ParamByName('ID').AsInteger:=integer(cbCategorie.Items.Objects[cbCategorie.ItemIndex]);
              ExecSQL;
         end;
         //rilegge tutti gli utenti e li carica nelle combo
         LoadComboCategorie();
         LoadComboCategorieparent();
         //pulisce tutti i campi
         ClearCampi();
    end
    //gli oggetti della categoria vanno cancellati
end;

procedure TCategorie.bteliminaextClick(Sender: TObject);
begin
  if MessageDlg('Si sta per eliminare '+edcampo.Text+' dal database. Continuare?',mtInformation, mbOKCancel, 0)=mrok then
begin

  //cancello il record selezionato
  with zq_categorie do
       Begin
            close;
            sql.Clear;
            sql.add('DELETE from CATEGORIE_EXT '+
                    'WHERE IDCATEGORIA_EXT=:IDCATEXT');
            ParamByName('IDCATEXT').AsInteger:=zq_ext.FieldByName('idcategoria_ext').AsInteger;
            ExecSQL;
       end;
  btnuovoextClick(self);
end;
end;


procedure TCategorie.btimageClick(Sender: TObject);
begin
  if OpenDialog1.Execute then
     begin
          edimage.Text:=OpenDialog1.FileName;
          Image1.Picture.LoadFromFile(edimage.Text);
     end;
end;

procedure TCategorie.btsalvaextClick(Sender: TObject);
begin
   //controllo che nome_campo sia valorizzato
  if edcampo.Text='' then
     begin
          ShowMessage('Valorizzare "Campo"');
          Exit();
     end;
  if edgruppo.Text='' then
     begin
          ShowMessage('Valorizzare "Gruppo"');
          Exit();
     end;
  //salvo o modifico il campo selezionato
  if btsalvaext.Caption='Salva' then
     begin
          //procedo con il salvataggio della MODIFICA
          with zq_categorie do
               begin
                    close;
                    sql.Clear;
                    sql.add('UPDATE CATEGORIE_EXT ' +
                            'SET NOME_CAMPO=:NOME, VALORE=:VALORE, GRUPPO=:GRUPPO '+
                            'WHERE IDCATEGORIA_EXT=:IDCATEXT');
                    ParamByName('NOME').AsString:=edcampo.Text;
                    ParamByName('VALORE').AsString:=edvalore.Text;
                    ParamByName('GRUPPO').AsInteger:=strtoint(edgruppo.Text);
                    ParamByName('IDCATEXT').AsInteger:=zq_ext.FieldByName('idcategoria_ext').AsInteger;
                    ExecSQL;
               end;
     end
  else
      begin
           //procedo con l'INSERIMENTO
            with zq_categorie do
               begin
                    close;
                    sql.Clear;
                    sql.add('INSERT INTO CATEGORIE_EXT ' +
                            '(IDCATEGORIA,NOME_CAMPO,VALORE,GRUPPO) '+
                            'VALUES (:IDCAT,:NOME,:VALORE,:GRUPPO)');
                    ParamByName('NOME').AsString:=edcampo.Text;
                    ParamByName('VALORE').AsString:=edvalore.Text;
                    ParamByName('GRUPPO').AsInteger:=strtoint(edgruppo.Text);
                    ParamByName('IDCAT').AsInteger:=integer(cbcategorie.Items.Objects[cbcategorie.ItemIndex]);
                    ExecSQL;
               end;
      end;
  //refresho la griglia e pulisco i campi
btnuovoextClick(self);
end;

procedure TCategorie.bttemplateClick(Sender: TObject);
begin
   if edgruppo.Text='' then
     begin
          ShowMessage('Valorizzare "Gruppo"');
          Exit();
     end;
//carico i campi custom del template nell'articolo corrente
if cbTemplate.ItemIndex <>-1 then
   begin
        with zq_categorie do
          begin
               Close;
               sql.Clear;
               sql.Add('INSERT INTO CATEGORIE_EXT (IDCATEGORIA,GRUPPO,NOME_CAMPO,VALORE) '+
                       'SELECT :IDCAT,:GRUPPO,NOME_CAMPO,VALORE FROM CATEGORIE_TEMPL_DATA WHERE IDTEMPLATE=:IDTEMPL');
               ParamByName('IDTEMPL').AsInteger:=integer(cbTemplate.Items.Objects[cbTemplate.ItemIndex]);
               ParamByName('IDCAT').AsInteger:=  integer(cbcategorie.Items.Objects[cbcategorie.ItemIndex]);
               ParamByName('GRUPPO').AsInteger:=StrToInt(edgruppo.Text);
               ExecSQL;
          end;
     end;
btnuovoextClick(self);
end;


procedure TCategorie.cbCategorieChange(Sender: TObject);
var stream:TMemoryStream;
begin
     stream:=TMemoryStream.Create;
     if cbCategorie.ItemIndex<>-1 then
     begin
     //mostro nei campi l'azienda selezionata
     with zq_categorie do
     begin
        Close;
        sql.Clear;
        sql.Add('SELECT * FROM CATEGORIE WHERE IDCATEGORIA=:ID');
        ParamByName('ID').AsInteger:=integer(cbCategorie.Items.Objects[cbCategorie.ItemIndex]);
        ExecSQL;
        Open;
        edNome.Text:=FieldByName('NOME').AsString;
        edDescrizione.Text:=FieldByName('DESCRIZIONE').AsString;
        ckgerarchica.Checked:=FieldByName('GERARCHICA').AsBoolean;
        if not FieldByName('immagine').IsNull then
          begin
               TBlobField(FieldByName('immagine')).SaveTostream(stream);
               stream.Position:=0;
               Image1.Picture.Jpeg.LoadFromStream(stream);
          end
        else
            Image1.Picture.Clear;
        stream.free;
        Close;

        sql.Clear;
        sql.Add('SELECT * FROM CATEGORIE_REL WHERE ID_CATEGORIA_CHILD=:ID');
        ParamByName('ID').AsInteger:=integer(cbCategorie.Items.Objects[cbCategorie.ItemIndex]);
        ExecSQL;
        Open;
        cbCategoriaParent.ItemIndex:= cbCategoriaParent.Items.IndexOfObject(TObject(FieldByName('ID_CATEGORIA_PARENT').AsInteger));
     end;
     with zq_ext do
         begin
              //seleziono tutti i campi che fanno capo a questo id
              close;
              sql.clear;
              sql.add('SELECT IDCATEGORIA_EXT,gruppo,NOME_CAMPO,VALORE FROM CATEGORIE_EXT '+
                      'WHERE IDCATEGORIA=:IDCAT '+
                      'ORDER BY gruppo,NOME_CAMPO');
              ParamByName('IDCAT').AsInteger:=integer(cbcategorie.Items.Objects[cbcategorie.ItemIndex]);
              ExecSQL;
              open;
         end;
         With grigliacampi do
              begin
                   Columns[0].Visible:=false;
                   Columns[1].Width:=50;
                   Columns[2].Width:=200;
                   Columns[3].Width:=200;
                   Columns[1].Title.Caption:=' ';
                   Columns[2].Title.Caption:='Campo';
                   Columns[3].Title.Caption:='Valore';

              end;
    Panel2.Enabled:=true;
   end;
end;

procedure TCategorie.cbCategorieExit(Sender: TObject);
begin
     (sender as TComboBox).ItemIndex := (sender as TComboBox).Items.IndexOfObject(TObject((sender as TComboBox).Items.Objects[(sender as TComboBox).ItemIndex])); //(sender as TComboBox).Items.IndexOf((sender as TComboBox).Text);
     (sender as TComboBox).OnChange(self);
end;

procedure TCategorie.cbCategorieKeyPress(Sender: TObject; var Key: char);
begin
    if key=#13 then
       SelectNext(sender as twincontrol,true,true);
end;

procedure TCategorie.ckgerarchicaChange(Sender: TObject);
begin
     LoadComboCategorieparent();
end;


procedure TCategorie.edNomeChange(Sender: TObject);
begin
  btsalva.Enabled:=true;
end;

//la procedura svuota tutti i campi delle textbox e elimina la selezione nelle combo
procedure TCategorie.ClearCampi();
 begin
  ckgerarchica.Checked:=false;
  cbCategorie.ClearSelection;
  cbCategoriaParent.ClearSelection;
  edNome.Clear;
  edDescrizione.Clear;
  cbCategoriaParent.ClearSelection;
  btsalva.Enabled:=false;
  edimage.Clear;
  OpenDialog1.FileName:='';
  Image1.Picture.Clear;
end;


procedure TCategorie.LoadComboCategorie();
begin
//svuota combo
cbCategorie.Clear;
getcategorychild(0,1);
end;

procedure TCategorie.getcategorychild(categoryparent,level:integer);
var dataset1 :TZQuery;
begin
//creo il dataset
dataset1:=TZQuery.Create(self);
dataset1.Connection:=DataModule1.ZConnection1;
with dataset1 do
     begin
          sql.clear;
          sql.add('SELECT ID_CATEGORIA_PARENT, ID_CATEGORIA_CHILD, IDCATEGORIA, NOME, GERARCHICA FROM CATEGORIE_REL, CATEGORIE');
          SQL.ADD('WHERE CATEGORIE_REL.ID_CATEGORIA_CHILD=CATEGORIE.IDCATEGORIA');
          SQL.ADD('AND ID_CATEGORIA_PARENT=:IDPARENT');
          SQL.ADD('AND IDDITTA=:IDDITTA');
          SQL.ADD('ORDER BY ID_CATEGORIA_CHILD ASC');
          ParamByName('IDPARENT').AsInteger:=categoryparent;
          ParamByName('IDdITTA').AsInteger:=DataModule1.idditta;
          ExecSQL;
          open;
          first;
          while not EOF do
                begin
                    cbCategorie.Items.AddObject(StringOfChar(' ', 2*level) + fieldbyname('nome').AsString,TObject(fieldbyname('idcategoria').AsInteger));

                    getcategorychild(fieldbyname('id_categoria_child').Asinteger,level+1);
                    next;
                end;
          close;
     end;
dataset1.Destroy;
end;

procedure TCategorie.LoadComboCategorieparent();
begin
//svuota combo
cbCategoriaParent.Clear;
cbCategoriaParent.Items.Add('Default-Categoria Madre');
getcategorychildparent(0,1);
end;

procedure TCategorie.getcategorychildparent(categoryparent,level:integer);
var dataset1 :TZQuery;
begin
//creo il dataset
dataset1:=TZQuery.Create(self);
dataset1.Connection:=DataModule1.ZConnection1;
with dataset1 do
     begin
          sql.clear;
          sql.add('SELECT ID_CATEGORIA_PARENT, ID_CATEGORIA_CHILD, IDCATEGORIA, NOME, GERARCHICA FROM CATEGORIE_REL, CATEGORIE');
          SQL.ADD('WHERE CATEGORIE_REL.ID_CATEGORIA_CHILD=CATEGORIE.IDCATEGORIA');
          SQL.ADD('AND ID_CATEGORIA_PARENT=:IDPARENT');
          SQL.ADD('AND IDDITTA=:IDDITTA');
          SQL.ADD('ORDER BY ID_CATEGORIA_CHILD ASC');
          ParamByName('IDPARENT').AsInteger:=categoryparent;
          ParamByName('IDDITTA').AsInteger:=DataModule1.idditta;
          ExecSQL;
          open;
          first;
          while not EOF do
                begin
                    if ckgerarchica.Checked=fieldbyname('gerarchica').AsBoolean then
                       cbCategoriaParent.Items.AddObject(StringOfChar(' ', 2*level) + fieldbyname('nome').AsString,TObject(fieldbyname('idcategoria').AsInteger));

                    getcategorychildparent(fieldbyname('id_categoria_child').Asinteger,level+1);
                    next;
                end;
          close;
     end;
FreeAndNil(dataset1);
end;

initialization
  {$I categorie_frm.lrs}

end.

